package view;

import assets.Icons;
import component.divider.Divider;
import component.layout.VFlowLayout;
import component.scroll.SmallMouseWheelListener;
import component.util.MaterialColors;
import control.Controllers;
import entity.ClipMessage;

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import javax.swing.*;
import javax.swing.border.EmptyBorder;

import static control.ClipBoardControl.getClipboardString;

public class ClipBoardView implements BasePage{
    private Executor singleThreadExecutor = Executors.newSingleThreadExecutor();
    private String oldMessage = "";
    private static final List<ClipMessage> messages = new ArrayList<>();
    private static boolean haveInstance = false;
    private Point oldP; // 上一次坐标,拖动窗口时用
    private TipWindow tw = null; // 提示框
    private JLabel title = null; // 栏目名称
    private JLabel close = null; // 关闭按钮
    private JLabel login = null;
    private JPanel toolBar = null;
    private JPanel messagePanel = null;
    private JScrollPane scrollPane;

    public void init() {
        BasePage.object.put("ClipBoardView", this);
        if (getClipboardString() != null){
            ClipMessage clipMessage = new ClipMessage(getClipboardString(), "pc", MainPage.username, "");
            oldMessage = getClipboardString();
            messages.add(clipMessage);
        }
        // 新建消息提示框
        tw = new TipWindow(300, 400);
        tw.setLayout(new BorderLayout());
        initToolBar();
        tw.add(toolBar, BorderLayout.NORTH);
        initMessagePanel();
        tw.add(scrollPane, BorderLayout.CENTER);
        Timer timer = new Timer(1000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                updatePage();
            }
        });
        timer.start();
    }

    void initToolBar(){
        title = new JLabel("云贴");
        close = new JLabel(Icons.close);
        // 设置提示框的边框,宽度和颜色
        tw.getRootPane().setBorder(
                BorderFactory.createMatteBorder(1, 1, 1, 1, Color.gray));
        title.setVerticalTextPosition(JLabel.CENTER);
        title.setFont(new Font("微软雅黑", Font.BOLD, 16));
        title.setBorder(new EmptyBorder(4,12,12,12));

        login = new JLabel("未登录");
        login.setFont(new Font("微软雅黑", Font.BOLD, 16));
        login.setVerticalTextPosition(JLabel.CENTER);
        login.setBorder(new EmptyBorder(4,12,12,12));

        if (MainPage.username.length() > 0){
            login.setForeground(MaterialColors.COSMO_BLUE);
        } else {
            login.setForeground(MaterialColors.COSMO_RED);
            login.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    LoginDialog.showLoginDialog(null,null);
                }
            });
        }

        close.setToolTipText("关闭");
        close.setCursor(null);
        close.setFocusable(false);
        close.setVerticalAlignment(JLabel.TOP);

        toolBar = new JPanel(new BorderLayout());
        toolBar.setBorder(new EmptyBorder(8,4,4,4));
        toolBar.add(title, BorderLayout.WEST);
        toolBar.add(login, BorderLayout.CENTER);
        toolBar.add(close, BorderLayout.EAST);
        toolBar.add(new Divider(), BorderLayout.SOUTH);
    }

    void initMessagePanel(){
        messagePanel = new JPanel(new VFlowLayout());
        scrollPane = new JScrollPane(messagePanel);
        scrollPane.setBorder(null);
        scrollPane.addMouseWheelListener(new SmallMouseWheelListener(20, scrollPane.getVerticalScrollBar()));
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        for (ClipMessage m: messages
        ) {
            messagePanel.add(new ContentCard(m));
        }
    }

    public void handle() {
        // 增加鼠标拖动事件
        title.addMouseMotionListener(new MouseMotionAdapter() {
            public void mouseDragged(MouseEvent e) {
                Point newP = new Point(e.getXOnScreen(), e.getYOnScreen());
                int x = tw.getX() + (newP.x - oldP.x);
                int y = tw.getY() + (newP.y - oldP.y);
                tw.setLocation(x, y);
                oldP = newP;
            }
        });
        // 鼠标按下时初始坐标,供拖动时计算用
        title.addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                oldP = new Point(e.getXOnScreen(), e.getYOnScreen());
            }
        });
        // 右上角关闭按钮事件
        close.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
                close();
            }

            public void mouseEntered(MouseEvent e) {
                close.setBorder(BorderFactory.createLineBorder(Color.gray));
            }

            public void mouseExited(MouseEvent e) {
                close.setBorder(null);
            }
        });
    }

    public void show() {
        if (!haveInstance){
            init();
            handle();
            tw.setAlwaysOnTop(true);
            tw.setUndecorated(true);
        } else {
            tw.initComponents();
        }
        tw.setVisible(true);
        haveInstance = true;
    }

    public void close() {
        tw.close();
    }

    @Override
    public void updatePage() {
        List<ClipMessage> clipMessages = Controllers.CLIP_BOARD_CONTROL.getMessages();
        if (clipMessages.size() > 0){
            messages.addAll(clipMessages);
            messagePanel.removeAll();
            for (int i = messages.size() - 1; i >= 0; i--) {
                messagePanel.add(new ContentCard(messages.get(i)));
            }
            messagePanel.validate();
            messagePanel.repaint();
            scrollPane.validate();
            scrollPane.repaint();
        }
        if (!oldMessage.equals(getClipboardString()) && getClipboardString() != null){
            oldMessage = getClipboardString();
            ClipMessage clipMessage = new ClipMessage(oldMessage, "pc", MainPage.username, "");
            messages.add(clipMessage);
            singleThreadExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    Controllers.CLIP_BOARD_CONTROL.upload(MainPage.username, clipMessage);
                }
            });
            messagePanel.removeAll();
            for (int i = messages.size() - 1; i >= 0; i--) {
                messagePanel.add(new ContentCard(messages.get(i)));
            }
            messagePanel.validate();
            messagePanel.repaint();
            scrollPane.validate();
            scrollPane.repaint();
        }
    }

    public void reLogin(){
        if (MainPage.username.length() > 0){
            login.setForeground(MaterialColors.COSMO_BLUE);
            login.setText("已登录:" + MainPage.username);
            for (MouseListener m:login.getMouseListeners()
                 ) {
                login.removeMouseListener(m);
            }
        }
    }

    public void reLogout(){
        if (MainPage.username.length() > 0){
            login.setForeground(MaterialColors.COSMO_RED);
            login.setText("未登录");
            login.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    LoginDialog.showLoginDialog(null,null);
                }
            });
        }
    }
}

